<?php 

namespace App\Models\Power;

use App\Models\Base\PowerBase;
use App\Models\Power\Pile;
use App\Models\Power\OperateLog;
use App\Models\Power\User;
use Illuminate\Support\Facades\DB;

class Order extends PowerBase {

    protected $table = 'cdz_electric_order';

    protected $fillable = [];

    protected $dates = [];

    public static $rules = [
        // Validation rules
    ];

    public $timestamps = false;

    /**
     * 根据uid查询所有订单(mysql redis)
     * params1 String $uid
     */
    public function myOrder($uid, $status = 0) {

        $query = self::query();
        $query -> where('user_uid', '=', $uid);
        $query -> whereStatusNotIn();
        $status && $query -> whereStatus($status);
        $data = $query -> get();

        if($data) {
            $user_model = new User();
            foreach($data as $key => $value) {
                $data[$key] = $this -> getPileInfo($data[$key]);
                $data[$key]['user_money'] = $user_model -> myMoney($uid)['money'];
            }
        }

        $redis_order = $this -> redis -> hgetall('CDZCHARGEORDER');
        // dd($redis_order);
        // dd($redis_order);
        // dd($status);
        if($redis_order) {
            $user_model = new User();
            foreach($redis_order as $key => $value) {
                $order = json_decode($value, true);
                if($order['user_uid'] == $uid && $order['status'] == $status) {
                    $pile = new Pile();
                    // $temp = ["no" => "","user_uid" => "", "begin" => 0,"end" => 0,"pile_no" => "","gun_no" => "",
                    // "amount" => "","money" => "","service" => "","way" => 0,"status" => 0,"back" => 2,"created_at" => 0, 'stop_name'=>''];
                    $temp = $pile -> getPileByOrder($order);
                    $temp['no'] = $order['no'];
                    $temp['user_uid'] = $uid;
                    $temp['begin'] = $order['begin'];
                    $temp['end'] = $order['end'];
                    $temp['pile_no'] = $order['pile_no'];
                    $temp['gun_no'] = $order['gun'];
                    $temp['amount'] = round($order['amount'],2);
                    $temp['money'] = round($order['money'],2);
                    $temp['service'] = round($order['service'],2);
                    $temp['way'] = 0;
                    $temp['status'] = $order['status'];
                    $temp['back'] = 2;
                    $temp['created_at'] = $order['created_at'];
                    $temp['stop_name'] = $temp['stop_name'];
                    $temp['user_money'] = $user_model -> myMoney($uid)['money'];
                    $data[] = $temp;
                }    
            }
        }

        return $data;
        
    }

    /**
     * 钱包单个详情,根据uid及订单号查询订单详情
     * params1 String $no
     * params2 String $uid
     */
    public function getDetailInfo($no, $uid) {

        $data = [];
        $data = self::where('no', '=', $no) -> where('user_uid', $uid) -> first();

        return $data;

    }

    /**
     * 充电订单详情
     * params1 String $no
     * params2 String $uid
     */
    public function getOrderDetail($no, $uid) {

        $data = [];
        $data = self::where('no', '=', $no) -> where('user_uid', $uid) -> first();
        //先查mysql订单
        if($data) {
            
            $data = $this -> getPileInfo($data);
            if($data['status']!=5) {
                unset($data['pay_time']);
            }
            //如果没有mysql订单则查redis订单
        } else {

            $temp = $this -> getOrderRedis($no);
            if($temp && in_array($temp['status'], [1,2,3,4])) {

                $pile = new Pile();
                $temp = $pile -> getPileByOrder($temp);
                $data['no'] = $temp['no'];
                $data['user_uid'] = $uid;
                // $data['user_id'] = $temp['user_id'];
                $data['begin'] = $temp['begin'];
                $data['end'] = $temp['end'];
                $data['pile_no'] = $temp['pile_no'];
                $data['gun_no'] = $temp['gun'];
                $data['amount'] = round($temp['amount'], 2);
                $data['money'] = round($temp['money'], 2);
                $data['service'] = round($temp['service'],2);
                $data['way'] = 0;
                $data['status'] = $temp['status'];
                $data['back'] = 2;
                $data['created_at'] = $temp['created_at'];
                $data['stop_name'] = $temp['stop_name'];
                $data['electric_fee'] = $temp['electric_fee'];
                $data['service_fee'] = $temp['service_fee'];
                
            }

        }

        return $data;

    }

    /**
     * 验证是否存在充电订单
     * @param int $uid
     */
    public function hOrder($uid = 0)
    {

        $orders = $this -> getOrderRedisAll();
        foreach ($orders as $order) {
            $order = json_decode($order, true);
            if ($order['user_uid'] == $uid&&($order['status']==1||$order['status']==2||$order['status']==3||$order['status']==4)) {
                $pile = new Pile();
                $order = $pile -> getPileByOrder($order);
                return $order;
            }
        }

        $order = self::where('user_uid', '=', $uid) -> where('status', '=', 4) -> first();

        if($order) {
            $order = $this -> getPileInfo($order);
        }

        return $order;

    }

    /**
     * 根据订单获取电桩，电站信息
     * @param array $order
     */
    public function getPileInfo($order) {

        $order['stop_name'] = '';
        $pile = $order -> pile;
        //如果存在电桩
        if($pile) {
            $price = $pile -> price -> toArray();
            $this_price = getOrderPrice($order['begin'], $price);
            $order['electric_fee'] = $this_price['ele'];
            $order['service_fee'] = $this_price['service'];
            //如果存在电站
            if($pile -> stop) {
                $name = $pile -> stop -> name;
                if($name) {
                    $order['stop_name'] = $name;
                } else {
                    $order['stop_name'] = '未知';
                }
            }
        } else {
            $order['pile_no'] = $order['pile_no'] . '（该电桩编号已更改或该电桩已下线）';
            $order['electric_fee'] = '未知';
            $order['service_fee'] = '未知';
        }

        unset($order['pile']);

        return $order;

    }

    /**
     * 根据订单获取正在充电订单
     * @param array $params
     */
    public function charging($uid) {

        $orders = $this -> getOrderRedisAll();

        foreach ($orders as $order) {
            $order = json_decode($order, true);
            if ($order['user_uid'] == $uid&&($order['status']==1||$order['status']==2||$order['status']==3)) {
                $order['money'] = $order['money'] ? round($order['money'], 2) : '0.00';
                $order['amount'] = $order['amount'] ? round($order['amount'], 2) : '0.00';
                if($order['soc']) {
                    $order['soc'] = round($order['soc']/100,2);
                } else {
                    $order['soc'] = 0;
                }
                $order['amount'] = round($order['amount'], 2);
                return $order;
            } 
        }

        return null;

    }



    /**
     * 根据订单号删除订单
     * @param string $no
     */
    public function delOrder($no) {

        $order = $this -> whereNo($no) -> first();

        if($order) {
            $order -> status = 6;
            $re = $order -> save();

            if($re) {
                return true;
            }

        } 

        return false;
    }
    

    /**
     * 处理开始充电的订单
     * params1 array $order
     */
    public function doOrder($order = []) {

        $this -> redis -> hset('CDZCHARGEORDER', $order['no'], json_encode($order));
        $this -> redis -> hset('CDZCHARGEORDERPILENO', $order['pile_no'] . '_' . $order['gun'], $order['no']);
        return $order;

    }

    /**
     * 订单支付通用方法
     * @param string $order_no 订单编号
     * @param int $way 付款方式
     * @return bool
     */
    public function pay_common($order_no, $way, $uid = '', $money = '') {
        
        $query = self::query();
        $query -> where('no', $order_no);
        $order = $query -> first();
        if($order->status != 4) {
            return true;
        }
        DB::connection('jmft_power') -> beginTransaction();
        $order -> way = $way;
        $order -> status = 5;
        $order -> pay_time = time();
        $order_save = $order -> save();
        if(!$order_save) {
            DB::connection('jmft_power') -> rollBack();
            return false;
        }
        
        if($way == 3) {
            $user_model = new User();
            $user_query = User::query();
            $user_query -> where('uid', $uid);
            $now_user = $user_model -> myMoney($uid);
            $user_save = $now_user -> addMoney($now_user['id'], $money);
        
            if(!$user_save) {
                DB::connection('jmft_power') -> rollBack();
                return false;
            }
        }

        if(isset($order->pile->operate)) {
            $operate = $order->pile->operate;
            
        } else {
            $operate = null;
        }
    
        if($operate&&$operate->status == 1) {

            $powerRate = $order->money - $order->service;
            $serviceRate = $order->service;
            // dd($powerRate);
            if (!OperateLog::addOperateLog($order->pile->owner, $order->no, ($powerRate * $operate->charge_y), ($serviceRate * $operate->service_y), 2)) {
                DB::connection('jmft_power') -> rollBack();
                return false;
            }
            if (!OperateLog::addOperateLog($order->pile->property, $order->no, ($powerRate * $operate->charge_w), ($serviceRate * $operate->service_w))) {
                DB::connection('jmft_power') -> rollBack();
                return false;
            }

            $commission = $operate->commission;
            if ($commission && $commission->status == 1) {
                $money = ($powerRate * $operate->charge_s) + ($serviceRate * $operate->service_s);
                $money = $money * 0.28;
                $user = $order->user;
                $ratios = [
                    1 => $commission->provincial_agent,
                    2 => $commission->city_agent,
                    3 => $commission->county_agent,
                    4 => $commission->station_agent,
                    5 => $commission->switch_agent,
                    6 => $commission->indirect_agent,
                    7 => $commission->direct_agent,
                    8 => $commission->self_agent,
                ];
                $users = User::getSellIncomeUser($user);
                foreach ($users as $k => $v) {
                    if ($v && $ratios[$k]) {
                        if ($nowMoney = round($ratios[$k] * $money, 2)) {
                            $insertData = ['income_type'=>$k, 'consume_id'=>$order->id, 'type'=>2, 'user_id'=>$v, 'money'=>(string)$nowMoney,
                            'created_at'=>time()];
                            $save_profit = DB::connection('jmft_power') -> table('cdz_profit') -> insert($insertData);
                            if (!$save_profit || !User::addIntegral($v, (string)$nowMoney)) {
                                DB::connection('jmft_power') -> rollBack();
                                return false;
                            }
                        }
                    }
                }
                $capital_pool_agent = $commission->capital_pool_agent;
                if ($capital_pool_agent) {
                    $insertData = ['consume_id'=>$order->id, 'money'=>(string)round($capital_pool_agent * $money, 2),'created_at'=>time()];
                    $save_capital = DB::connection('jmft_power') -> table('cdz_capital_money') -> insert($insertData);
                    if (!$save_capital) {
                        DB::connection('jmft_power') -> rollBack();
                        return false;
                    } else {
                        DB::connection('jmft_power') ->commit();
                        return true;
                    }
                } else {
                    DB::connection('jmft_power') ->commit();
                    return true;
                }
            } else {
                DB::connection('jmft_power') ->commit();
                return true;
            }
        }

        DB::connection('jmft_power') ->commit();
        return true;

    }
    /**
     * 订单支付
     * params1 string $order_no 订单编号
     * params2 int $way 付款方式
     */
    public function pay($order_no, $way, $uid = '', $money = '') {

        if($redis_order = $this -> getOrderRedis($order_no)) {
            $synRe = $this -> synchroOrder($redis_order);
            if($synRe) {
                return $this -> pay_common($order_no, $way, $uid, $money);
            } else {
                return false;
            }
        } else {
            return $this -> pay_common($order_no, $way, $uid, $money);
        }

    }

    /**
     * 订单同步
     * params1 array $redis_order
     */
    public function synchroOrder($redis_order) {

        $query = self::query();
        $insert_data = [
            'no' => $redis_order['no'],
            'user_id' => $redis_order['user_id'],
            'pile_no' => $redis_order['pile_no'],
            'gun_no' => $redis_order['gun'],
            'begin' => $redis_order['begin'],
            'end' => $redis_order['end'],
            'money' => (string) $redis_order['money'],
            'service' => (string) $redis_order['service'],
            'amount' => (string) $redis_order['amount'],
            'created_at' => $redis_order['created_at'],
            'user_uid' => $redis_order['user_uid'],
            'status' => 4,
            'type' => $redis_order['type']
        ];
        $order = $query -> insertGetId($insert_data);
        if($order) {
            $this -> delROrder($redis_order['no']);
            return true; 
        } else {
            return false;
        }

    }

    public function scopeWhereStatusNotIn($query) {

        return $query -> whereNotIn('status', [6,7]);

    }

    /**
     * 和Pile模型的一对一关联
     */
    public function pile() {
        return $this -> hasOne('App\Models\Power\Pile', 'no', 'pile_no');
    }

    /**
     * 和User模型的一对一关联
     */
    public function user() {
        return $this -> hasOne('App\Models\Power\User', 'uid', 'user_uid');
    }

}
